using System;
using System.Linq;
using Domain.Dto;
using Domain.Interface;
using Domain.Model;
using Gmmy.DomainExtension;
using Gmmy.Utility;
using Surging.Core.CPlatform.Ioc;
using System.Threading.Tasks;

namespace Domain.Services
{
    public class RoleDomainService : ServiceBase, IRoleDomainService
    {
        private readonly IRoleRepository _repository;
        private readonly IModuleActionRepository _moduleActionRepository;
        private readonly IRoleModuleRelationRepository _moduleRelationRepository;

        public RoleDomainService(IRoleRepository repository, IRoleModuleRelationRepository moduleRelationRepository,
            IModuleActionRepository moduleActionRepository)
        {
            this._repository = repository;
            _moduleRelationRepository = moduleRelationRepository;
            _moduleActionRepository = moduleActionRepository;
        }

        /// <summary>
        /// 创建角色
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Create(RoleCreateInput input)
        {
            var model = new Role(input);
            if (input.ActionList == null)
            {
                throw new CustomException("请选择至少一个功能!");
            }
            var dbactions = (await _moduleActionRepository.GetManyAsync(
                new DirectSpecification<ModuleAction>(x => !x.IsDeleted && input.ActionList.Contains(x.ID)))).ToList();
            dbactions.ForEach(x =>
            {
                _moduleRelationRepository.Add(new RoleModuleRelation(model.ID, x.ModuleId, x.ID));
            });
            _repository.Add(model);
        }

        /// <summary>
        /// 更新角色
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Update(RoleUpdateInput input)
        {
            var model = await _repository.GetByKeyAsync(input.ID);
            if (model == null)
            {
                throw new CustomException("所选角色不存在!");
            }
            model.Update(input);
            var oldActions =
            (await _moduleRelationRepository.GetManyAsync(
                new DirectSpecification<RoleModuleRelation>(x => !x.IsDeleted && x.RoleId == model.ID))).ToList();
            _moduleRelationRepository.LogicDelete(new DirectSpecification<RoleModuleRelation>(x =>
                oldActions.Select(y => y.ID).Except(input.ActionList).Contains(x.ID)));
            (await _moduleActionRepository.GetManyAsync(
                    new DirectSpecification<ModuleAction>(x =>
                        !x.IsDeleted && input.ActionList.Except(oldActions.Select(y => y.ID)).Contains(x.ID)))).ToList()
                .ToList().ForEach(x =>
                {
                    _moduleRelationRepository.Add(new RoleModuleRelation(model.ID, x.ModuleId, x.ID));
                });
            _repository.Modify(model);
        }
    }
}
